package com.hxzy.es.service;

import com.baizhi.common.vo.PageVO;
import com.hxzy.dto.GoodsInfoSearch;
import com.hxzy.es.entity.EsGoodsInfo;
import com.hxzy.es.repository.EsGoodsInfoRepository;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class EsGoodsInfoService {

    @Autowired
    private EsGoodsInfoRepository esGoodsInfoRepository;

    /**
     * 复杂查询
     */
    @Autowired
    private ElasticsearchRestTemplate  elasticsearchRestTemplate;

    /**
     * 查询价格
     * @param min
     * @param max
     * @return
     */
    public List<EsGoodsInfo> findBySellingPrice(int min,int max){
        return this.esGoodsInfoRepository.findBySellingPriceBetween(min,max);
    }

    public EsGoodsInfo findById(Long id){
        Optional<EsGoodsInfo> optional = this.esGoodsInfoRepository.findById(id);
        if(optional.isPresent()){
            return optional.get();
        }
        return null;
    }


    /**
     *  分页查询
     * @param goodsInfoSearch
     * @return
     */
    public PageVO search(GoodsInfoSearch goodsInfoSearch){


        //1、构造分页对象
        Sort orderBy = Sort.by(Sort.Direction.ASC, "sellingPrice");

        Pageable  pageable=PageRequest.of(goodsInfoSearch.getPage()-1, goodsInfoSearch.getSize(),orderBy);



        //2、搜索条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.multiMatchQuery(goodsInfoSearch.getName(), "goods_name", "goods_intro"));

        //如果分类不为空
        if(goodsInfoSearch.getCategoryId()!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("goods_category_id",goodsInfoSearch.getCategoryId()));
        }

        //如果价格不为空
        if(goodsInfoSearch.getMinPrice()!=null && goodsInfoSearch.getMaxPrice()!=null){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("selling_price").gte(goodsInfoSearch.getMinPrice()).lte(goodsInfoSearch.getMaxPrice()));
        }


        //3、构造查询对象 NativeSearchQuery   --> restful风格查询
        /*
        GET /hxzy_mall/_search?from=1&size=10
            {
              "query": {
                "multi_match": {
                  "query": "游戏",
                  "fields": ["goods_name","goods_intro"]
                }
              },
              "highlight": {
                "fields": {
                  "goods_name": {
                    "pre_tags": "<b style='color:red;'>",
                    "post_tags": "</b>"

                  }
                }
              }
            }
         */
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .withHighlightFields(new HighlightBuilder.Field("goods_name"))
                .withHighlightBuilder(new HighlightBuilder().preTags("<b style='color:red;'>").postTags("</em>"))
                .build();

        //4、发送查询请求
        SearchHits<EsGoodsInfo> searchHits = this.elasticsearchRestTemplate.search(nativeSearchQuery, EsGoodsInfo.class);

        //5、自定义组装对象
        PageVO  pageVO=new PageVO();
        pageVO.setTotal( searchHits.getTotalHits());
       
        List<EsGoodsInfo> arrList=new ArrayList<>();
        
        //6、组装最复杂的数据
        List<SearchHit<EsGoodsInfo>> searchHitsList = searchHits.getSearchHits();
        for (SearchHit<EsGoodsInfo>  searchHit:searchHitsList) {

            EsGoodsInfo esGoodsInfo = searchHit.getContent();
            //判断是否有高亮标签列
            List<String> goodsNameHighlightField = searchHit.getHighlightField("goods_name");
            if(!goodsNameHighlightField.isEmpty()){
                esGoodsInfo.setGoodsName(  goodsNameHighlightField.get(0));
            }
            arrList.add(esGoodsInfo);
        }

        pageVO.setRows(arrList);

        return pageVO;
    }


}
